package org.example.util;

import org.example.util.collection.MapUtil;
import org.example.annotation.CanQueryProperty;
import org.example.annotation.QueryLikeType;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 反射相关工具类
 *
 * @author Maple
 * @date 2023-11-22
 */
@Slf4j
public class ReflectUtil {



    public static Long getId(Object obj) {

        try {
            Method get = obj.getClass().getMethod("getId");
            Object invoke = get.invoke(obj);
            if(null == invoke) return null;
            return Long.parseLong(String.valueOf(invoke));

        } catch (Exception e) {
            log.error("该对象没有getId方法！ {}", obj.toString());
            throw new RuntimeException(e);
        }

    }

    @SuppressWarnings("unchecked")
    public static <T> T getFieldValue (String fieldName, Object obj) {
        try {
            try {
                Field field = obj.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                return (T) field.get(obj);
            } catch (NoSuchFieldException e) {
                String getterName = "get" + fieldName.substring(0, 1).toUpperCase()
                        + fieldName.substring(1);
                Method method = obj.getClass().getMethod(getterName);
                return (T) method.invoke(obj);
            }
        } catch (Exception e) {
            log.error("该对象没有{}字段！ {}", fieldName, obj);
            throw new RuntimeException(e);
        }
    }


    public static boolean hasField (String fieldName, Object obj) {
        try {
            Field field = obj.getClass().getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            return false;
        }
        return true;
    }

    public static <V> void setFieldValue (String fieldName, V value, Object obj) {
        try {

            Field field = obj.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(obj, value);

        } catch (Exception e) {
            log.error("该对象没有{}字段！ {}", fieldName, obj);
            throw new RuntimeException(e);
        }
    }

    public static Map<String, QueryLikeType> getCanLikeByLikeKeys(Class<?> aClass) {
        Map<String, QueryLikeType> res = MapUtil.getSmallMap(7);
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            if(field.isAnnotationPresent(CanQueryProperty.class)) {
                CanQueryProperty annotation = field.getAnnotation(CanQueryProperty.class);
                QueryLikeType value = annotation.value();
                res.put(field.getName(), value);
            }
        }
        return res;
    }

}
